home *** CD-ROM | disk | FTP | other *** search
/ Ultra Pack / UltraComputing Partner Applications.iso / SunLabs / tclTK / src / tk4.0 / tkCanvUtil.c < prev    next >
C/C++ Source or Header  |  1994-12-17  |  11KB  |  393 lines

  1. /* 
  2.  * tkCanvUtil.c --
  3.  *
  4.  *    This procedure contains a collection of utility procedures
  5.  *    used by the implementations of various canvas item types.
  6.  *
  7.  * Copyright (c) 1994 Sun Microsystems, Inc.
  8.  * Copyright (c) 1994 Sun Microsystems, Inc.
  9.  *
  10.  * See the file "license.terms" for information on usage and redistribution
  11.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12.  */
  13.  
  14. static char sccsid[] = "@(#) tkCanvUtil.c 1.2 94/12/17 16:32:33";
  15.  
  16. #include "tk.h"
  17. #include "tkCanvas.h"
  18. #include "tkPort.h"
  19.  
  20. /*
  21.  * Custom option for handling "-tags" options for canvas items:
  22.  */
  23.  
  24. static int        CanvasTagsParseProc _ANSI_ARGS_((ClientData clientData,
  25.                 Tcl_Interp *interp, Tk_Window tkwin, char *value,
  26.                 char *widgRec, int offset));
  27. static char *        CanvasTagsPrintProc _ANSI_ARGS_((ClientData clientData,
  28.                 Tk_Window tkwin, char *widgRec, int offset,
  29.                 Tcl_FreeProc **freeProcPtr));
  30.  
  31. Tk_CustomOption tk_CanvasTagsOption = {
  32.     CanvasTagsParseProc,
  33.     CanvasTagsPrintProc,
  34.     (ClientData) NULL
  35. };
  36.  
  37. /*
  38.  *----------------------------------------------------------------------
  39.  *
  40.  * Tk_CanvasTkwin --
  41.  *
  42.  *    Given a token for a canvas, this procedure returns the
  43.  *    widget that represents the canvas.
  44.  *
  45.  * Results:
  46.  *    The return value is a handle for the widget.
  47.  *
  48.  * Side effects:
  49.  *    None.
  50.  *
  51.  *----------------------------------------------------------------------
  52.  */
  53.  
  54. Tk_Window
  55. Tk_CanvasTkwin(canvas)
  56.     Tk_Canvas canvas;            /* Token for the canvas. */
  57. {
  58.     TkCanvas *canvasPtr = (TkCanvas *) canvas;
  59.     return canvasPtr->tkwin;
  60. }
  61.  
  62. /*
  63.  *----------------------------------------------------------------------
  64.  *
  65.  * Tk_CanvasDrawableCoords --
  66.  *
  67.  *    Given an (x,y) coordinate pair within a canvas, this procedure
  68.  *    returns the corresponding coordinates at which the point should
  69.  *    be drawn in the drawable used for display.
  70.  *
  71.  * Results:
  72.  *    There is no return value.  The values at *drawableXPtr and
  73.  *    *drawableYPtr are filled in with the coordinates at which
  74.  *    x and y should be drawn.  These coordinates are clipped
  75.  *    to fit within a "short", since this is what X uses in
  76.  *    most cases for drawing.
  77.  *
  78.  * Side effects:
  79.  *    None.
  80.  *
  81.  *----------------------------------------------------------------------
  82.  */
  83.  
  84. void
  85. Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr)
  86.     Tk_Canvas canvas;            /* Token for the canvas. */
  87.     double x, y;            /* Coordinates in canvas space. */
  88.     short *drawableXPtr, *drawableYPtr;    /* Screen coordinates are stored
  89.                      * here. */
  90. {
  91.     TkCanvas *canvasPtr = (TkCanvas *) canvas;
  92.     double tmp;
  93.  
  94.     tmp = x - canvasPtr->drawableXOrigin;
  95.     if (tmp > 0) {
  96.     tmp += 0.5;
  97.     } else {
  98.     tmp -= 0.5;
  99.     }
  100.     if (tmp > 32767) {
  101.     *drawableXPtr = 32767;
  102.     } else if (tmp < -32768) {
  103.     *drawableXPtr = -32768;
  104.     } else {
  105.     *drawableXPtr = tmp;
  106.     }
  107.  
  108.     tmp = y  - canvasPtr->drawableYOrigin;
  109.     if (tmp > 0) {
  110.     tmp += 0.5;
  111.     } else {
  112.     tmp -= 0.5;
  113.     }
  114.     if (tmp > 32767) {
  115.     *drawableYPtr = 32767;
  116.     } else if (tmp < -32768) {
  117.     *drawableYPtr = -32768;
  118.     } else {
  119.     *drawableYPtr = tmp;
  120.     }
  121. }
  122.  
  123. /*
  124.  *----------------------------------------------------------------------
  125.  *
  126.  * Tk_CanvasWindowCoords --
  127.  *
  128.  *    Given an (x,y) coordinate pair within a canvas, this procedure
  129.  *    returns the corresponding coordinates in the canvas's window.
  130.  *
  131.  * Results:
  132.  *    There is no return value.  The values at *screenXPtr and
  133.  *    *screenYPtr are filled in with the coordinates at which
  134.  *    (x,y) appears in the canvas's window.  These coordinates
  135.  *    are clipped to fit within a "short", since this is what X
  136.  *    uses in most cases for drawing.
  137.  *
  138.  * Side effects:
  139.  *    None.
  140.  *
  141.  *----------------------------------------------------------------------
  142.  */
  143.  
  144. void
  145. Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr)
  146.     Tk_Canvas canvas;            /* Token for the canvas. */
  147.     double x, y;            /* Coordinates in canvas space. */
  148.     short *screenXPtr, *screenYPtr;    /* Screen coordinates are stored
  149.                      * here. */
  150. {
  151.     TkCanvas *canvasPtr = (TkCanvas *) canvas;
  152.     double tmp;
  153.  
  154.     tmp = x - canvasPtr->xOrigin;
  155.     if (tmp > 0) {
  156.     tmp += 0.5;
  157.     } else {
  158.     tmp -= 0.5;
  159.     }
  160.     if (tmp > 32767) {
  161.     *screenXPtr = 32767;
  162.     } else if (tmp < -32768) {
  163.     *screenXPtr = -32768;
  164.     } else {
  165.     *screenXPtr = tmp;
  166.     }
  167.  
  168.     tmp = y  - canvasPtr->yOrigin;
  169.     if (tmp > 0) {
  170.     tmp += 0.5;
  171.     } else {
  172.     tmp -= 0.5;
  173.     }
  174.     if (tmp > 32767) {
  175.     *screenYPtr = 32767;
  176.     } else if (tmp < -32768) {
  177.     *screenYPtr = -32768;
  178.     } else {
  179.     *screenYPtr = tmp;
  180.     }
  181. }
  182.  
  183. /*
  184.  *--------------------------------------------------------------
  185.  *
  186.  * Tk_CanvasGetCoord --
  187.  *
  188.  *    Given a string, returns a floating-point canvas coordinate
  189.  *    corresponding to that string.
  190.  *
  191.  * Results:
  192.  *    The return value is a standard Tcl return result.  If
  193.  *    TCL_OK is returned, then everything went well and the
  194.  *    canvas coordinate is stored at *doublePtr;  otherwise
  195.  *    TCL_ERROR is returned and an error message is left in
  196.  *    interp->result.
  197.  *
  198.  * Side effects:
  199.  *    None.
  200.  *
  201.  *--------------------------------------------------------------
  202.  */
  203.  
  204. int
  205. Tk_CanvasGetCoord(interp, canvas, string, doublePtr)
  206.     Tcl_Interp *interp;        /* Interpreter for error reporting. */
  207.     Tk_Canvas canvas;        /* Canvas to which coordinate applies. */
  208.     char *string;        /* Describes coordinate (any screen
  209.                  * coordinate form may be used here). */
  210.     double *doublePtr;        /* Place to store converted coordinate. */
  211. {
  212.     TkCanvas *canvasPtr = (TkCanvas *) canvas;
  213.     if (Tk_GetScreenMM(canvasPtr->interp, canvasPtr->tkwin, string,
  214.         doublePtr) != TCL_OK) {
  215.     return TCL_ERROR;
  216.     }
  217.     *doublePtr *= canvasPtr->pixelsPerMM;
  218.     return TCL_OK;
  219. }
  220.  
  221. /*
  222.  *----------------------------------------------------------------------
  223.  *
  224.  * Tk_CanvasSetStippleOrigin --
  225.  *
  226.  *    This procedure sets the stipple origin in a graphics context
  227.  *    so that stipples drawn with the GC will line up with other
  228.  *    stipples previously drawn in the canvas.
  229.  *
  230.  * Results:
  231.  *    None.
  232.  *
  233.  * Side effects:
  234.  *    The graphics context is modified.
  235.  *
  236.  *----------------------------------------------------------------------
  237.  */
  238.  
  239. void
  240. Tk_CanvasSetStippleOrigin(canvas, gc)
  241.     Tk_Canvas canvas;        /* Token for a canvas. */
  242.     GC gc;            /* Graphics context that is about to be
  243.                  * used to draw a stippled pattern as
  244.                  * part of redisplaying the canvas. */
  245.  
  246. {
  247.     TkCanvas *canvasPtr = (TkCanvas *) canvas;
  248.  
  249.     XSetTSOrigin(canvasPtr->display, gc, -canvasPtr->drawableXOrigin,
  250.         -canvasPtr->drawableYOrigin);
  251. }
  252.  
  253. /*
  254.  *----------------------------------------------------------------------
  255.  *
  256.  * Tk_CanvasGetTextInfo --
  257.  *
  258.  *    This procedure returns a pointer to a structure containing
  259.  *    information about the selection and insertion cursor for
  260.  *    a canvas widget.  Items such as text items save the pointer
  261.  *    and use it to share access to the information with the generic
  262.  *    canvas code.
  263.  *
  264.  * Results:
  265.  *    The return value is a pointer to the structure holding text
  266.  *    information for the canvas.  Most of the fields should not
  267.  *    be modified outside the generic canvas code;  see the user
  268.  *    documentation for details.
  269.  *
  270.  * Side effects:
  271.  *    None.
  272.  *
  273.  *----------------------------------------------------------------------
  274.  */
  275.  
  276. Tk_CanvasTextInfo *
  277. Tk_CanvasGetTextInfo(canvas)
  278.     Tk_Canvas canvas;            /* Token for the canvas widget. */
  279. {
  280.     return &((TkCanvas *) canvas)->textInfo;
  281. }
  282.  
  283. /*
  284.  *--------------------------------------------------------------
  285.  *
  286.  * CanvasTagsParseProc --
  287.  *
  288.  *    This procedure is invoked during option processing to handle
  289.  *    "-tags" options for canvas items.
  290.  *
  291.  * Results:
  292.  *    A standard Tcl return value.
  293.  *
  294.  * Side effects:
  295.  *    The tags for a given item get replaced by those indicated
  296.  *    in the value argument.
  297.  *
  298.  *--------------------------------------------------------------
  299.  */
  300.  
  301. static int
  302. CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset)
  303.     ClientData clientData;        /* Not used.*/
  304.     Tcl_Interp *interp;            /* Used for reporting errors. */
  305.     Tk_Window tkwin;            /* Window containing canvas widget. */
  306.     char *value;            /* Value of option (list of tag
  307.                      * names). */
  308.     char *widgRec;            /* Pointer to record for item. */
  309.     int offset;                /* Offset into item (ignored). */
  310. {
  311.     register Tk_Item *itemPtr = (Tk_Item *) widgRec;
  312.     int argc, i;
  313.     char **argv;
  314.     Tk_Uid *newPtr;
  315.  
  316.     /*
  317.      * Break the value up into the individual tag names.
  318.      */
  319.  
  320.     if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {
  321.     return TCL_ERROR;
  322.     }
  323.  
  324.     /*
  325.      * Make sure that there's enough space in the item to hold the
  326.      * tag names.
  327.      */
  328.  
  329.     if (itemPtr->tagSpace < argc) {
  330.     newPtr = (Tk_Uid *) ckalloc((unsigned) (argc * sizeof(Tk_Uid)));
  331.     for (i = itemPtr->numTags-1; i >= 0; i--) {
  332.         newPtr[i] = itemPtr->tagPtr[i];
  333.     }
  334.     if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
  335.         ckfree((char *) itemPtr->tagPtr);
  336.     }
  337.     itemPtr->tagPtr = newPtr;
  338.     itemPtr->tagSpace = argc;
  339.     }
  340.     itemPtr->numTags = argc;
  341.     for (i = 0; i < argc; i++) {
  342.     itemPtr->tagPtr[i] = Tk_GetUid(argv[i]);
  343.     }
  344.     ckfree((char *) argv);
  345.     return TCL_OK;
  346. }
  347.  
  348. /*
  349.  *--------------------------------------------------------------
  350.  *
  351.  * CanvasTagsPrintProc --
  352.  *
  353.  *    This procedure is invoked by the Tk configuration code
  354.  *    to produce a printable string for the "-tags" configuration
  355.  *    option for canvas items.
  356.  *
  357.  * Results:
  358.  *    The return value is a string describing all the tags for
  359.  *    the item referred to by "widgRec".  In addition, *freeProcPtr
  360.  *    is filled in with the address of a procedure to call to free
  361.  *    the result string when it's no longer needed (or NULL to
  362.  *    indicate that the string doesn't need to be freed).
  363.  *
  364.  * Side effects:
  365.  *    None.
  366.  *
  367.  *--------------------------------------------------------------
  368.  */
  369.  
  370. static char *
  371. CanvasTagsPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
  372.     ClientData clientData;        /* Ignored. */
  373.     Tk_Window tkwin;            /* Window containing canvas widget. */
  374.     char *widgRec;            /* Pointer to record for item. */
  375.     int offset;                /* Ignored. */
  376.     Tcl_FreeProc **freeProcPtr;        /* Pointer to variable to fill in with
  377.                      * information about how to reclaim
  378.                      * storage for return string. */
  379. {
  380.     register Tk_Item *itemPtr = (Tk_Item *) widgRec;
  381.  
  382.     if (itemPtr->numTags == 0) {
  383.     *freeProcPtr = (Tcl_FreeProc *) NULL;
  384.     return "";
  385.     }
  386.     if (itemPtr->numTags == 1) {
  387.     *freeProcPtr = (Tcl_FreeProc *) NULL;
  388.     return (char *) itemPtr->tagPtr[0];
  389.     }
  390.     *freeProcPtr = (Tcl_FreeProc *) free;
  391.     return Tcl_Merge(itemPtr->numTags, (char **) itemPtr->tagPtr);
  392. }
  393.